﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Jq.Respository;
using Jq.Service.Interface;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace WebApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile("config.json", optional: true, reloadOnChange: true);

            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //Use a MS SQL Server database
            var sqlConnectionString = Configuration.GetConnectionString("DataAccessMsSqlServerProvider");

            services.AddDbContext<DomainModelMsSqlServerContext>(options =>
                options.UseSqlServer(
                    sqlConnectionString,
                    b => b.MigrationsAssembly("WebApp")
                )
            );

            //DI 注入
            //services.AddScoped<IDataAccessProvider, DataAccessMsSqlServerProvider>();
            //集中注册服务
            //foreach (var item in GetClassName("Jq.Respository"))
            //{
            //    foreach (var typeArray in item.Value)
            //    {
            //        services.AddScoped(typeArray, item.Key);
            //    }
            //}
            foreach (var item in GetClassName("Jq.Service"))
            {
                foreach (var typeArray in item.Value)
                {
                    services.AddScoped(typeArray, item.Key);
                }
            }
            services.AddTransient(typeof(IDataAccessProvider<>), typeof(DataAccessMsSqlServerProvider<>));

            IServiceProvider serviceProvider = services.BuildServiceProvider();
            //IServiceProvider serviceProvider = new ServiceCollection()
            //    .AddTransient(typeof(IDataAccessProvider<>), typeof(DataAccessMsSqlServerProvider<>))
            //    .BuildServiceProvider();
            var user = serviceProvider.GetService(typeof(IDataAccessProvider<Jq.Domain.User>));
            var user1 = serviceProvider.GetService<IUser>();

            //dotnet ef migrations add mssqlMigration --context DomainModelMsSqlServerContext --project WebApp
            //dotnet ef database update --context DomainModelMsSqlServerContext --project WebApp

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, DomainModelMsSqlServerContext context)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();

            //开启自动同步数据库
            //new DbInitializer().Initializer(context);
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetService<DomainModelMsSqlServerContext>().Database.Migrate();

                var _provider = serviceScope.ServiceProvider.GetRequiredService<IUser>();
                //var _provider = serviceScope.ServiceProvider.GetRequiredService<IDataAccessProvider<Jq.Domain.User>>();
            }
        }

        /// <summary>  
        /// 获取程序集中的实现类对应的多个接口
        /// </summary>  
        /// <param name="assemblyName">程序集</param>
        public Dictionary<Type, Type[]> GetClassName(string assemblyName)
        {
            if (!String.IsNullOrEmpty(assemblyName))
            {
                Assembly assembly = Assembly.Load(assemblyName);
                List<Type> ts = assembly.GetTypes().ToList();

                var result = new Dictionary<Type, Type[]>();
                foreach (var item in ts.Where(s => !s.IsInterface))
                {
                    var interfaceType = item.GetInterfaces();
                    result.Add(item, interfaceType);
                }
                return result;
            }
            return new Dictionary<Type, Type[]>();
        }
    }
}
